package com.ncmem.up7.controller;

import com.google.gson.Gson;
import com.ncmem.down3.biz.FolderBuilder;
import com.ncmem.up7.DBConfig;
import com.ncmem.up7.DBFile;
import com.ncmem.up7.DBFolder;
import com.ncmem.up7.PathTool;
import com.ncmem.up7.biz.DbFolder;
import com.ncmem.up7.biz.PathGuidBuilder;
import com.ncmem.up7.biz.up7_biz_event;
import com.ncmem.up7.model.FileInf;
import com.ncmem.up7.sql.SqlExec;
import com.ncmem.up7.sql.SqlParam;
import com.ncmem.up7.sql.SqlWhereMerge;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import java.io.IOException;

public class FileMgrApi {

    /**
     * 加载数据，前端调用。
     * @param pageSize  页大小
     * @param pageIndex 页索引
     * @param pid       父ID
     * @return
     */
    @RequestMapping(value={"filemgr/data","filemgr/search"},method = RequestMethod.GET)
    public String load_data(@RequestParam(value="limit",required = false,defaultValue = "20")Integer pageSize,
                            @RequestParam(value="page",required = false,defaultValue = "1")Integer pageIndex,
                            @RequestParam(value="pid",required = false,defaultValue = "")String pid
    )
    {
        SqlWhereMerge swm = new SqlWhereMerge();
        swm.equal("f_complete", 1);
        swm.equal("f_deleted", 0);
        swm.equal("f_fdChild", 1);
        swm.equal("f_pid", pid,false);//

        boolean isRoot = StringUtils.isEmpty(pid);//根目录
        if(isRoot) swm.equal("f_fdChild", 0);

        String where = swm.to_sql();

        SqlExec se = new SqlExec();
        JSONArray arr = se.page("up7_files"
                ,"f_id"
                , "f_id,f_pid,f_nameLoc,f_sizeLoc,f_lenLoc,f_time,f_pidRoot,f_fdTask,f_pathSvr,f_pathRel"
                , pageSize
                , pageIndex
                , where
                , "f_fdTask desc,f_time desc");

        //加载目录表
        JSONArray folders = new JSONArray();
        if(!isRoot)
        {
            swm.del("f_fdChild");
            where = swm.to_sql();
            folders = se.page("up7_folders"
                    , "f_id"
                    , "f_id,f_nameLoc,f_pid,f_sizeLoc,f_time,f_pidRoot,f_pathRel"
                    , pageSize
                    , pageIndex
                    , where
                    , "f_time desc");

            for(int i = 0 ; i < folders.size() ; i++)
            {
                JSONObject fd = (JSONObject) folders.get(i);
                fd.put("f_fdTask", true);
                fd.put("f_fdChild", false);
                fd.put("f_pathSvr", "");

                arr.add(fd);
            }
        }

        JSONObject o = new JSONObject();
        o.put("count", se.count("up7_files", where));
        o.put("code", 0);
        o.put("msg", "");
        o.put("data", arr);

        //if(toParam) this.m_wb.param.put("items", o);
        return o.toString();
    }

    /**
     * 重命名逻辑，由前端调用。
     * @param pid 父级ID
     * @param id 文件或目录ID
     * @param nameNew 新名称
     * @param folder  是文件夹？
     * @return
     */
    @RequestMapping(value="filemgr/rename",method = RequestMethod.GET)
    public String rename(@RequestParam(value="f_pid", required=false,defaultValue="")String pid,
                           @RequestParam(value="f_id", required=false,defaultValue="")String id,
                           @RequestParam(value="f_nameLoc", required=false,defaultValue="")String nameNew,
                           @RequestParam(value="f_fdTask", required=false,defaultValue="")Boolean folder
    )
    {
        nameNew = PathTool.url_decode(nameNew);
        if (folder)
            return this.rename_folder(pid,id,nameNew);
        else return this.rename_file(pid,id, nameNew);
    }

    /**
     * 重命名文件
     * @param pid
     * @param id
     * @param name
     * @return
     */
    String rename_file(String pid, String id, String name)
    {
        boolean ret = DBFile.existSameFile(name, pid);
        if (ret)
        {
            JSONObject v = new JSONObject();
            v.put("state", false);
            v.put("msg", "存在同名文件");
            v.put("code", "102");
            //var v = new JObject { { "state",false},{ "msg","存在同名文件"},{ "code","102"} };
            return v.toString();
        }
        else
        {
            SqlExec se = new SqlExec();
            //更新相对路径：/test/test.jpg
            JSONObject info = se.read("up7_files", "f_pathRel", new SqlParam[] {new SqlParam("f_id",id)});
            String pathRel = info.getString("f_pathRel");
            Integer pos = pathRel.lastIndexOf('/');
            pathRel = pathRel.substring(0, pos+1);
            pathRel = pathRel.concat(name);

            //更新名称
            se.update("up7_files",
                    new SqlParam[] {
                            new SqlParam("f_nameLoc",name),
                            new SqlParam("f_nameSvr",name),
                            new SqlParam("f_pathRel",pathRel)
                    },
                    new SqlParam[] {
                            new SqlParam("f_id",id)
                    }
            );

            JSONObject v = new JSONObject();
            v.put("state", true);
            return v.toString();
        }
    }

    /**
     * 重命名目录
     * @param pid
     * @param id
     * @param name
     * @return
     */
    String rename_folder(String pid,String id,String name) {
        boolean ext = DbFolder.existSameFolder(name, pid);
        if(ext)
        {
            JSONObject v = new JSONObject();
            v.put("state", false);
            v.put("msg", "存在同名目录");
            v.put("code", "102");
            return v.toString();
        }
        else
        {
            //取pathRoot=/test，并构造新路径
            String pathRelNew = DbFolder.getPathRel(id);
            String pathRelOld = pathRelNew;//旧的路径,pathRoot=/test
            Integer index = pathRelNew.lastIndexOf('/');
            pathRelNew = pathRelNew.substring(0, index + 1);
            pathRelNew = pathRelNew + name;

            //更新文件名称
            SqlExec se = new SqlExec();
            if(StringUtils.isEmpty(pid) )//根目录
            {
                se.update("up7_files",
                        new SqlParam[] {
                                new SqlParam("f_nameLoc",name),
                                new SqlParam("f_nameSvr",name)
                        },
                        new SqlParam[] {
                                new SqlParam("f_id",id)
                        }
                );

                //更新文件夹路径
                se.update("up7_files", new SqlParam[] {
                                new SqlParam("f_pathRel",pathRelNew)
                        },
                        new SqlParam[] {
                                new SqlParam("f_id",id)
                        }
                );
            }
            else
            {
                se.update("up7_folders",
                        new SqlParam[] {
                                new SqlParam("f_nameLoc",name),
                        },
                        new SqlParam[] {
                                new SqlParam("f_id",id)
                        }
                );

                //更新文件夹路径
                se.update("up7_folders", new SqlParam[] {
                                new SqlParam("f_pathRel",pathRelNew)
                        },
                        new SqlParam[] {
                                new SqlParam("f_id",id)
                        }
                );
            }

            DBConfig dc = new DBConfig();
            dc.db().updatePathRel(pathRelOld, pathRelNew);
            dc.folder().updatePathRel(pathRelOld, pathRelNew);

            JSONObject v = new JSONObject();
            v.put("state", true);
            return  v.toString();
        }
    }

    /**
     * 删除目录或目录
     * @param id 文件或目录ID，由前端提供
     * @return
     */
    @RequestMapping(value = "filemgr/del",method = RequestMethod.GET)
    String del(@RequestParam(value = "id",required = false,defaultValue = "")String id)
    {
        SqlExec se = new SqlExec();
        se.update("up7_files",
                new SqlParam[] {new SqlParam("f_deleted",true)},
                new SqlParam[] {
                        new SqlParam("f_id",id),
                        new SqlParam("f_pid",id),
                        new SqlParam("f_pidRoot",id)
                },
                "or");
        se.update("up7_folders",
                new SqlParam[] {new SqlParam("f_deleted",true)},
                new SqlParam[] {
                        new SqlParam("f_id",id),
                        new SqlParam("f_pid",id),
                        new SqlParam("f_pidRoot",id)
                },
                "or");

        JSONObject ret = new JSONObject();
        ret.put("ret", 1);
        return ret.toString();
    }

    /**
     * 批量删除文件或目录
     * @param data
     * @return
     */
    @RequestMapping(value = "filemgr/del_batch",method = RequestMethod.GET)
    String del_batch(@RequestParam(value = "data",required = false,defaultValue = "")String data)
    {
        data = PathTool.url_decode(data);
        JSONArray o = JSONArray.fromObject(data);

        SqlExec se = new SqlExec();
        se.exec_batch("up7_files", "update up7_files set f_deleted=1 where f_id=?", "", "f_id", o);
        se.exec_batch("up7_folders", "update up7_folders set f_deleted=1 where f_id=?", "", "f_id", o);

        JSONObject ret = new JSONObject();
        ret.put("ret", 1);
        return ret.toString();
    }

    /**
     * 生成导航路径
     * @param data
     * @return
     */
    @RequestMapping(value = "filemgr/build_path",method = RequestMethod.GET)
    String build_path(@RequestParam(value = "data",required = false,defaultValue = "")String data)
    {
        data = PathTool.url_decode(data);
        JSONObject fd = JSONObject.fromObject(data);

        DbFolder df = new DbFolder();
        return df.build_path(fd).toString();
    }

    /**
     * 创建目录
     * @param pid 父ID，前端提供
     * @param pathRel 相对路径，前端提供
     * @param nameLoc 目录名称，前端提供
     * @return
     */
    @RequestMapping(value = "filemgr/mk_folder",method = RequestMethod.GET)
    String mk_folder(@RequestParam(value = "f_pid",required = false,defaultValue = "")String pid,
                     @RequestParam(value = "f_pathRel",required = false,defaultValue = "")String pathRel,
                     @RequestParam(value = "f_nameLoc",required = false,defaultValue = "")String nameLoc)
    {
        pathRel = PathTool.url_decode(pathRel);
        nameLoc = PathTool.url_decode(nameLoc);

        //存在同名文件
        if (DbFolder.existSameFolder(nameLoc, pid))
        {
            JSONObject ret = new JSONObject();
            ret.put("state", false);
            ret.put("msg", "存在同名文件");
            return ret.toString();
        }

        SqlExec se = new SqlExec();
        String guid = PathTool.guid();

        //根目录
        if (StringUtils.isEmpty(pid))
        {
            se.insert("up7_files", new SqlParam[] {
                    new SqlParam("f_id",guid)
                    ,new SqlParam("f_pid","")
                    ,new SqlParam("f_pidRoot","")
                    ,new SqlParam("f_pathRel",PathTool.combine(pathRel,nameLoc))
                    ,new SqlParam("f_nameLoc",nameLoc)
                    ,new SqlParam("f_complete",true)
                    ,new SqlParam("f_fdTask",true)
            });
        }//子目录
        else
        {
            se.insert("up7_folders", new SqlParam[] {
                    new SqlParam("f_id",guid)
                    ,new SqlParam("f_pid",pid)
                    ,new SqlParam("f_pidRoot","")
                    ,new SqlParam("f_pathRel",PathTool.combine(pathRel,nameLoc))
                    ,new SqlParam("f_nameLoc",nameLoc)
                    ,new SqlParam("f_complete",true)
            });
        }

        JSONObject o = new JSONObject();
        o.put("state", true);
        o.put("f_id", guid);
        o.put("f_pathRel", pathRel);
        return o.toString();
    }

    /**
     * 加载未上传完的任务列表
     * @return
     */
    @RequestMapping(value = "filemgr/uncomp",method = RequestMethod.GET)
    String uncomp()
    {
        SqlExec se = new SqlExec();
        JSONArray files = se.exec("up7_files"
                , "select f_id as id,f_nameLoc as nameLoc,f_pathLoc as pathLoc,f_sizeLoc as sizeLoc,f_lenSvr as lenSvr,f_perSvr as perSvr,f_fdTask as fdTask from up7_files where f_complete=0 and f_fdChild=0 and f_deleted=0"
                , "f_id,f_nameLoc,f_pathLoc,f_sizeLoc,f_lenSvr,f_perSvr,f_fdTask"
                , "id,nameLoc,pathLoc,sizeLoc,lenSvr,perSvr,fdTask");
        return files.toString();
    }

    /**
     * 加载未下载完的任务列表
     * @param uid 用户ID，前端提供
     * @return
     */
    @RequestMapping(value = "filemgr/uncmp_down",method = RequestMethod.GET)
    String uncmp_down(@RequestParam(value = "uid",required = false,defaultValue = "0")Integer uid)
    {
        SqlExec se = new SqlExec();
        JSONArray files = se.select("down3_files"
                , "f_id,f_nameLoc,f_pathLoc,f_perLoc,f_sizeSvr,f_fdTask"
                , new SqlParam[] {new SqlParam("f_uid",uid)}
                , ""
        );
        return files.toString();
    }

    /**
     * 文件初始化，验证同名文件。
     * @param uid
     * @param pathRel
     * @param pathLoc
     * @param cbk
     * @param id
     * @param lenLoc
     * @param md5
     * @param pid
     * @param pidRoot
     * @param sizeLoc
     * @return
     */
    @RequestMapping(value = "filemgr/f_create",method = RequestMethod.GET)
    String f_create(@RequestParam(value = "pid",required = false,defaultValue = "")String pid,
                    @RequestParam(value = "pidRoot",required = false,defaultValue = "")String pidRoot,
                    @RequestParam(value = "md5",required = false,defaultValue = "")String md5,
                    @RequestParam(value = "id",required = false,defaultValue = "")String id,
                    @RequestParam(value = "uid",required = false,defaultValue = "0")Integer uid,
                    @RequestParam(value = "lenLoc",required = false,defaultValue = "0")Long lenLoc,
                    @RequestParam(value = "sizeLoc",required = false,defaultValue = "")String sizeLoc,
                    @RequestParam(value = "callback",required = false,defaultValue = "")String cbk,
                    @RequestParam(value = "pathLoc",required = false,defaultValue = "")String pathLoc,
                    @RequestParam(value = "pathRel",required = false,defaultValue = "")String pathRel
    )
    {
        //客户端使用的是encodeURIComponent编码，
        pathLoc = PathTool.url_decode(pathLoc);//utf-8解码
        pathRel = PathTool.url_decode(pathRel);

        //参数为空
        if (   StringUtils.isEmpty(sizeLoc))
        {
            return cbk + "({\"value\":null})" ;
        }

        FileInf fileSvr = new FileInf();
        fileSvr.f_fdChild = false;
        fileSvr.uid = uid;//将当前文件UID设置为当前用户UID
        fileSvr.id = id;
        fileSvr.pid = pid;
        fileSvr.f_fdChild = !StringUtils.isEmpty(pid);
        fileSvr.pidRoot = pidRoot;
        fileSvr.nameLoc = PathTool.getName(pathLoc);
        fileSvr.pathLoc = pathLoc;
        fileSvr.pathRel = PathTool.combine(pathRel, fileSvr.nameLoc);
        fileSvr.lenLoc = lenLoc;
        fileSvr.sizeLoc = sizeLoc;
        fileSvr.deleted = false;
        fileSvr.md5 = md5;
        fileSvr.nameSvr = fileSvr.nameLoc;

        //所有单个文件均以uuid/file方式存储
        PathGuidBuilder pb = new PathGuidBuilder();
        try {
            fileSvr.pathSvr = pb.genFile(fileSvr);
        } catch (IOException e) {
            e.printStackTrace();
        }

        //同名文件检测
        if (DBFile.existSameFile(fileSvr.nameLoc, fileSvr.pid))
        {
            String data = cbk + "({'value':'','ret':false,'code':'101'})";
            return data;
        }

        //
        DBFile df = new DBFile();
        df.add(fileSvr);

        //触发事件
        up7_biz_event.file_create(fileSvr);

        Gson gson = new Gson();
        String json = gson.toJson(fileSvr);
        json = PathTool.url_encode(json);
        json = cbk + "({\"value\":\"" + json + "\",\"ret\":true})";//返回jsonp格式数据。
        return json;
    }

    /**
     * 文件夹初始化
     * @param pid
     * @param pidRoot
     * @param md5
     * @param id
     * @param uid
     * @param lenLoc
     * @param sizeLoc
     * @param cbk
     * @param pathLoc
     * @param pathRel
     * @return
     */
    @RequestMapping(value = "filemgr/fd_create",method = RequestMethod.GET)
    String fd_create(@RequestParam(value = "pid",required = false,defaultValue = "")String pid,
                     @RequestParam(value = "id",required = false,defaultValue = "")String id,
                     @RequestParam(value = "sizeLoc",required = false,defaultValue = "")String sizeLoc,
                    @RequestParam(value = "pidRoot",required = false,defaultValue = "")String pidRoot,
                    @RequestParam(value = "md5",required = false,defaultValue = "")String md5,
                    @RequestParam(value = "uid",required = false,defaultValue = "0")Integer uid,
                     @RequestParam(value = "filesCount",required = false,defaultValue = "0")Integer fileCount,
                    @RequestParam(value = "lenLoc",required = false,defaultValue = "0")Long lenLoc,
                    @RequestParam(value = "callback",required = false,defaultValue = "")String cbk,
                    @RequestParam(value = "pathLoc",required = false,defaultValue = "")String pathLoc,
                    @RequestParam(value = "pathRel",required = false,defaultValue = "")String pathRel
    )
    {
        pathRel = PathTool.url_decode(pathRel);
        pathLoc = PathTool.url_decode(pathLoc);

        FileInf f = new FileInf();
        f.nameLoc = PathTool.getName(pathLoc);
        f.nameSvr = f.nameLoc;
        f.f_fdChild = !StringUtils.isEmpty(pid);
        f.id = id;
        f.pid = pid;
        f.pathLoc = pathLoc;
        f.sizeLoc = sizeLoc;
        f.lenLoc = lenLoc;
        f.fileCount = fileCount;
        f.pathRel = PathTool.combine(pathRel,f.nameLoc);
        f.fdTask = true;
        f.uid = uid;
        //生成路径，格式：upload/年/月/日/guid/文件夹名称
        PathGuidBuilder pb = new PathGuidBuilder();
        try {
            f.pathSvr = pb.genFolder(f.uid, f.id,f.nameLoc);
        } catch (IOException e) {
            e.printStackTrace();
        }
        f.pathSvr = f.pathSvr.replace("\\", "/");
        PathTool.createDirectory(f.pathSvr);

        //添加到队列表
        DBConfig cfg = new DBConfig();
        DBFile db = cfg.db();
        db.add(f);

        //添加到文件夹表
        DBFolder dbf = cfg.folderDB();
        dbf.add(f);

        //触发事件
        up7_biz_event.folder_create(f);

        Gson gson   = new Gson();
        String json = gson.toJson(f);
        json = PathTool.url_encode(json);
        json = cbk + "({\"value\":\"" + json + "\"})";//返回jsonp格式数据。
        return json;
    }

    /**
     * 获取目录文件总数
     * @param id 目录ID
     * @return
     */
    @RequestMapping(value = "filemgr/count",method = RequestMethod.GET)
    String fd_data_count( @RequestParam(value = "id",required = false,defaultValue = "")String id
    )
    {
        if (StringUtils.isEmpty(id)) return "";

        FolderBuilder fb = new FolderBuilder();
        Integer c = fb.count(id);
        long totalSz = fb.totalSize(id);
        JSONObject obj = new JSONObject();
        obj.put("count", c);
        obj.put("totalSize", totalSz);

        return obj.toString();
    }

    /**
     * 获取目录数据
     * @param id 目录ID
     * @param page 页索引
     * @return
     */
    @RequestMapping(value = "filemgr/page",method = RequestMethod.GET)
    String fd_data( @RequestParam(value = "id",required = false,defaultValue = "")String id,
                    @RequestParam(value = "page",required = false,defaultValue = "0")Integer page
    )
    {
        if (StringUtils.isEmpty(id)) return "";

        FolderBuilder fb = new FolderBuilder();
        String json = fb.build(page, id);
        json = PathTool.url_encode(json);
        return json;
    }
}
